{{!

  Copyright (c) Meta Platforms, Inc. and affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}{{!
The argument and result types for functions on thrift services (and interactions)
}}{{#service:supported_functions}}


class {{> types/function_args_type}}(metaclass={{> types/struct_metaclass}}):
    _fbthrift_SPEC = (
        {{#function:args}}
        _fbthrift_python_types.FieldInfo(
            {{field:id}},  # id
            _fbthrift_python_types.FieldQualifier.Unqualified, # qualifier
            "{{field:name}}",  # name
            "{{field:py_name}}",  # python name (from @python.Name annotation)
            {{#field:type}}{{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }}{{/field:type}},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
            {{field:idl_type}}, # IDL type (see BaseTypeEnum)
        ),
        {{/function:args}}
    )
{{^function:oneway?}}


class _fbthrift_{{service:name}}_{{function:name}}_result(metaclass={{> types/struct_metaclass}}):
    _fbthrift_SPEC = (
        {{#function:regular_response_type}}
        {{^type:void?}}
        _fbthrift_python_types.FieldInfo(
            0,  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "success",  # name
            "success", # name
            {{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
        ),
        {{/type:void?}}
        {{/function:regular_response_type}}
        {{#function:exceptions}}
        _fbthrift_python_types.FieldInfo(
            {{field:id}},  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "_ex{{field:index}}__{{field:name}}",  # name
            "{{> fields/exception_field_name}}",  # python name (from @python.Name annotation)
            {{#field:type}}{{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }}{{/field:type}},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
            {{field:idl_type}}, # IDL type (see BaseTypeEnum)
        ),
        {{/function:exceptions}}
    )
{{/function:oneway?}}
{{#function:stream?}}


class _fbthrift_{{service:name}}_{{function:name}}_result_stream_elem(metaclass={{> types/struct_metaclass}}):
    _fbthrift__rpc_kind = _fbthrift__RpcKind.SINGLE_REQUEST_STREAMING_RESPONSE
    _fbthrift_SPEC = (
        {{#function:stream_elem_type}}
        _fbthrift_python_types.FieldInfo(
            0,  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "success",  # name
            "success", # name
            {{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
        ),
        {{/function:stream_elem_type}}
        {{#function:stream_exceptions}}
        _fbthrift_python_types.FieldInfo(
            {{field:id}},  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "_ex{{field:index}}__{{field:name}}",  # name
            "{{> fields/exception_field_name}}",  # python name (from @python.Name annotation)
            {{#field:type}}{{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }}{{/field:type}},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
            {{field:idl_type}}, # IDL type (see BaseTypeEnum)
        ),
        {{/function:stream_exceptions}}
    )
{{/function:stream?}}
{{#function:sink?}}


class _fbthrift_{{service:name}}_{{function:name}}_result_sink_elem(metaclass={{> types/struct_metaclass}}):
    _fbthrift__rpc_kind = _fbthrift__RpcKind.SINK
    _fbthrift_SPEC = (
        {{#function:sink_elem_type}}
        _fbthrift_python_types.FieldInfo(
            0,  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "success",  # name
            "success", # name
            {{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
        ),
        {{/function:sink_elem_type}}
        {{#function:sink_exceptions}}
        _fbthrift_python_types.FieldInfo(
            {{field:id}},  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "_ex{{field:index}}__{{field:name}}",  # name
            "{{> fields/exception_field_name}}",  # python name (from @python.Name annotation)
            {{#field:type}}{{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }}{{/field:type}},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
            {{field:idl_type}}, # IDL type (see BaseTypeEnum)
        ),
        {{/function:sink_exceptions}}
    )

    @classmethod
    async def _fbthrift__sink_elem_handler(
        cls,
        sink_agen: _typing_AsyncGenerator[{{!
            }}{{#function:sink_elem_type}}{{> types/pep484_type}}{{!
            }}{{/function:sink_elem_type}}, None],
        protocol: _fbthrift__Protocol,
    ) -> _typing_AsyncGenerator[_fbthrift_iobuf, None]:
        {{#if (array.empty? function:sink.exceptions)}}
        async for item in sink_agen:
            yield serialize_iobuf(cls(success=item), protocol)
        {{#else}}
        try:
            async for item in sink_agen:
                yield serialize_iobuf(cls(success=item), protocol)
        {{#function:sink_exceptions}}{{#field:type}}
        except {{#type:need_module_path?}}{{type:module_mangle}}.{{/type:need_module_path?}}{{!
                }}{{#type:structured}}{{> structs/unadapted_name}}{{/type:structured}} as e:
            return_struct = cls({{> fields/exception_field_name}}=e)
            buf = serialize_iobuf(return_struct, protocol)
            exp = _fbthrift__PythonUserException("{{type:module_name}}.{{type:name}}", str(e), buf)
            raise exp
        {{/field:type}}
        {{/function:sink_exceptions}}
        {{/if (array.empty? function:sink.exceptions)}}


class _fbthrift_{{service:name}}_{{function:name}}_result_sink_final(metaclass={{> types/struct_metaclass}}):
    _fbthrift_SPEC = (
        {{#function:sink_final_response_type}}
        _fbthrift_python_types.FieldInfo(
            0,  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "success",  # name
            "success", # name
            {{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
        ),
        {{/function:sink_final_response_type}}
        {{#function:sink_final_response_exceptions}}
        _fbthrift_python_types.FieldInfo(
            {{field:id}},  # id
            _fbthrift_python_types.FieldQualifier.Optional, # qualifier
            "_ex{{field:index}}__{{field:name}}",  # name
            "{{> fields/exception_field_name}}",  # python name (from @python.Name annotation)
            {{#field:type}}{{^type:primitive?}}lambda: {{/type:primitive?}}{{> types/typeinfo }}{{/field:type}},  # typeinfo
            None,  # default value
            {{> fields/adapter_info }},  # adapter info
            {{> fields/is_primitive }}, # field type is primitive
            {{field:idl_type}}, # IDL type (see BaseTypeEnum)
        ),
        {{/function:sink_final_response_exceptions}}
    )
{{/function:sink?}}
{{/service:supported_functions}}
